﻿//-----------------------------------------------------------------------
// <copyright file="HtmlRetriever.cs" company="Redmist">
//     Copyright (c) Damien T Smith. All rights reserved.
// </copyright>
// <author>Damien Smith</author>
//-----------------------------------------------------------------------

namespace Redmist.UsageMonitor.WebIO
{
    using System.IO;
    using System.Net;

    /// <summary>Handles the retrieval of usage data in HTML format from the aaNet web site.</summary>
    public static class HtmlRetriever
    {
        /// <summary>A System.String representing the URI used for session security.</summary>
        private const string CookieDomain = "www.aanet.com.au";

        /// <summary>A System.String representing the path used for the session cookie.</summary>
        private const string CookiePath = "/";

        /// <summary>A System.String representing the text found on the usage page if login failed.</summary>
        private const string AuthenticationFailedHint = "You are not currently logged in";

        /// <summary>Retrieves usage statistics from the aaNet web site.</summary>
        /// <param name="serviceNumber">A System.String representing an aaNet user service number.</param>
        /// <param name="password">A System.String representing a password for the aaNet member's account.</param>
        /// <returns>A Redmist.UsageMonitor.WebIO.UsageRetrievalResult representing a usage data retrieval result.</returns>
        public static UsageRetrievalResult RetrieveUsageHtmlPage(string serviceNumber, string password)
        {
            string postData = string.Format("servicenumber={0}&password={1}", serviceNumber, password);
            UsageRetrievalResult usageRetrievalResult = new UsageRetrievalResult();

            try
            {
                IHttpWebRequest request = WebRequestFactory.CreateInitialWebRequest(postData);
                IHttpWebResponse response = request.GetResponse();
                response.Close();
                Cookie sessionCookie = CreateSessionCookie(response, CookieDomain, CookiePath);
                request = WebRequestFactory.CreateUsageRequest(sessionCookie);
                usageRetrievalResult.HtmlResult = RetrieveUsageData(request, response);
                if (usageRetrievalResult.HtmlResult.Contains(AuthenticationFailedHint))
                {
                    usageRetrievalResult.UsageRetrievalStatus = UsageRetrievalStatus.AuthenticationError;
                }
                else
                {
                    usageRetrievalResult.UsageRetrievalStatus = UsageRetrievalStatus.OK;
                }
            }
            catch (WebException webException)
            {
                switch (webException.Status)
                {
                    case WebExceptionStatus.Timeout:
                        usageRetrievalResult.UsageRetrievalStatus = UsageRetrievalStatus.Timeout;
                        break;
                    default:
                        usageRetrievalResult.UsageRetrievalStatus = UsageRetrievalStatus.ConnectionError;
                        break;
                }
            }

            return usageRetrievalResult; 
        }

        /// <summary>Creates a security cookie based on the value in the header of a web response.</summary>
        /// <param name="httpWebResponse">A Redmist.UsageMonitor.WebIO.IHttpWebResponse representing a HTTP response.</param>
        /// <param name="domain">A System.String representing the URI for which the cookie is valid.</param>
        /// <param name="path">A System.String representing the subset of URIs on the origin server to which this System.Net.Cookie applies.</param>
        /// <returns>A System.Net.Cookie representing a cookie containing a session ID.</returns>
        public static Cookie CreateSessionCookie(IHttpWebResponse httpWebResponse, string domain, string path)
        {
            string cookieHeader = httpWebResponse.Headers["Set-Cookie"];
            string[] cookies = cookieHeader.Split('=');
            string[] sessionId = cookies[1].Split(';');
            return new Cookie(cookies[0], sessionId[0], path, domain);
        }

        /// <summary>Retrieves usage data.</summary>
        /// <param name="request">A Redmist.UsageMonitor.WebIO.IHttpWebRequest representing a HTTP request.</param>
        /// <param name="response">A Redmist.UsageMonitor.WebIO.IHttpWebResponse representing a HTTP response.</param>
        /// <returns>A System.String representing a HTML usage page.</returns>
        public static string RetrieveUsageData(IHttpWebRequest request, IHttpWebResponse response)
        {
            response = request.GetResponse();
            string pageText;
            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader streamReader = new StreamReader(responseStream))
                {
                    pageText = streamReader.ReadToEnd();
                }
            }

            return pageText;
        }
    }
}
